/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.mindbox.mueblesalpes.negocio.entity;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Temporal;

/**
 * Clase que representa una venta de productos.
 * @author jsanchez
 */
@Entity
@Table(name="venta")
public class Venta implements Serializable,Cloneable {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_VENTA")
    @SequenceGenerator(name = "SEQ_VENTA", allocationSize = 1, sequenceName = "venta_seq")
    private Long idVenta;

    private String referencia;

    @OneToMany(mappedBy="venta", cascade=CascadeType.ALL)
    private List<Compra> compras;

    @OneToMany(mappedBy="venta", cascade=CascadeType.ALL)
    private List<CategoriaValor> categoriasValor;
    private double valorTotal;

    @OneToOne(optional=false)
    private Cliente cliente;
    @OneToOne(optional=false)
    private Usuario usuario;

    @Temporal(javax.persistence.TemporalType.DATE)
    private Date fecha;

    @OneToOne
    private Entidad entidad;
    @OneToOne(optional=true, cascade=CascadeType.ALL)
    private DatosTarjeta datosTarjeta;

    private boolean ventaPagada;

    /**
     * Crea una venta con sus atributos por defecto.
     */
    public Venta() {
        this.compras = new ArrayList<Compra>();
        this.categoriasValor = new ArrayList<CategoriaValor>();
        this.fecha = Calendar.getInstance().getTime();
    }

    /**
     * Obtiene los datos de la tarjeta
     * @return DatosTarjeta
     */
    public DatosTarjeta getDatosTarjeta() {
        return datosTarjeta;
    }

    /**
     * Coloca los datos de la tarjeta
     * @param datosTarjeta
     */
    public void setDatosTarjeta(DatosTarjeta datosTarjeta) {
        this.datosTarjeta = datosTarjeta;
    }

    /**
     * Obtiene la entidad
     * @return Entidad
     */
    public Entidad getEntidad() {
        return entidad;
    }

    /**
     * Coloca la entidad
     * @param entidad
     */
    public void setEntidad(Entidad entidad) {
        this.entidad = entidad;
    }

    /**
     * Obtiene la fecha
     * @return Date
     */
    public Date getFecha() {
        return fecha;
    }

    /**
     * Coloca la fecha
     * @param fecha
     */
    public void setFecha(Date fecha) {
        this.fecha = fecha;
    }

    /**
     * Obtiene la referencia
     * @return String
     */
    public String getReferencia() {
        return referencia;
    }

    /**
     * Coloca la referencia
     * @param referencia
     */
    public void setReferencia(String referencia) {
        this.referencia = referencia;
    }

    /**
     * Obtiene las categorías valor
     * @return List<CategoriaValor>
     */
    public List<CategoriaValor> getCategoriasValor() {
        return categoriasValor;
    }

    /**
     * Coloca las categorias valor
     * @param categoriasValor
     */
    public void setCategoriasValor(List<CategoriaValor> categoriasValor) {
        this.categoriasValor = categoriasValor;
    }

    /**
     * Obtiene el cliente
     * @return Cliente
     */
    public Cliente getCliente() {
        return cliente;
    }

    /**
     * Coloca el cliente.
     * @param cliente
     */
    public void setCliente(Cliente cliente) {
        this.cliente = cliente;
    }

    /**
     * Obtiene las compras de la venta
     * @return List<Compra>
     */
    public List<Compra> getCompras() {
        return compras;
    }

    /**
     * Coloca las compras
     * @param compras
     */
    public void setCompras(List<Compra> compras) {
        this.compras = compras;
    }

    /**
     * Obtiene el usuario.
     * @return Usuario
     */
    public Usuario getUsuario() {
        return usuario;
    }

    /**
     * Coloca el usuario.
     * @param usuario
     */
    public void setUsuario(Usuario usuario) {
        this.usuario = usuario;
    }

    /**
     * Obtiene el valor Total.
     * @return double
     */
    public double getValorTotal() {
        return valorTotal;
    }

    /**
     * Coloca el valor total.
     * @param valorTotal
     */
    public void setValorTotal(double valorTotal) {
        this.valorTotal = valorTotal;
    }

    /**
     * Obtiene el Id de la venta
     * @return Long
     */
    public Long getIdVenta() {
        return idVenta;
    }

    /**
     * Coloca el Id de la venta.
     * @param idVenta
     */
    public void setIdVenta(Long idVenta) {
        this.idVenta = idVenta;
    }
    @Override
    public Object clone() throws CloneNotSupportedException {
        Venta v = new Venta();

        v.setCategoriasValor(new ArrayList<CategoriaValor>());
        for(CategoriaValor cv : this.getCategoriasValor()){
            CategoriaValor cvClone = (CategoriaValor)cv.clone();
            cvClone.setVenta(v);
            v.getCategoriasValor().add(cvClone);
        }

        v.setCompras(new ArrayList<Compra>());
        for(Compra c : this.getCompras()){
            Compra cClone = (Compra)c.clone();
            cClone.setVenta(v);
            v.getCompras().add(cClone);
        }

        if(this.getCliente() != null)
            v.setCliente((Cliente)this.getCliente().clone());

        if(this.getDatosTarjeta() != null)
            v.setDatosTarjeta((DatosTarjeta)this.getDatosTarjeta().clone());
        
        if(this.getEntidad() != null)
            v.setEntidad((Entidad)this.getEntidad().clone());

        if(this.getUsuario() != null)
            v.setUsuario((Usuario)this.getUsuario().clone());

        v.setFecha(this.getFecha());
        v.setIdVenta(this.getIdVenta());
        v.setReferencia(this.getReferencia());
        v.setValorTotal(this.getValorTotal());
        
        return v;
    }

    @Override
    public boolean equals(Object obj) {
        if(obj != null && obj instanceof Venta &&
                this.getIdVenta() != null &&
                ((Venta)obj).getIdVenta() != null)
            return this.getIdVenta().equals(((Venta)obj).getIdVenta());
        return false;
    }

    @Override
    public int hashCode() {
        if(this.getIdVenta() == null)
            return 0;
        return this.getIdVenta().hashCode();
    }

    /**
     * @return the ventaPagada
     */
    public boolean isVentaPagada() {
        return ventaPagada;
    }

    /**
     * @param ventaPagada the ventaPagada to set
     */
    public void setVentaPagada(boolean ventaPagada) {
        this.ventaPagada = ventaPagada;
    }
}